package cn.wolfcode.mq.listener;

import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.OrderInfo;
import cn.wolfcode.mq.DefaultMessageSendCallback;
import cn.wolfcode.mq.MQConstant;
import cn.wolfcode.mq.OrderMQResult;
import cn.wolfcode.mq.OrderMessage;
import cn.wolfcode.service.IOrderInfoService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

/**
 * 监听MQ中创建订单的主题，然后进行订单的创建
 */
@Slf4j
@RocketMQMessageListener(
        consumerGroup = MQConstant.ORDER_PENDING_CONSUMER_GROUP,
        topic = MQConstant.ORDER_PENDING_TOPIC
)
@Component
public class OrderPendingMessageListener implements RocketMQListener<OrderMessage> {

    @Autowired
    private IOrderInfoService orderInfoService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void onMessage(OrderMessage message) {
        log.info("[创建订单] 收到创建订单消息,准备开始创建订单:{}", JSON.toJSONString(message));
        OrderMQResult orderMQResult = new OrderMQResult();
        orderMQResult.setToken(message.getToken());
        orderMQResult.setSeckillId(message.getSeckillId());
        orderMQResult.setTime(message.getTime());
        try {
            //扣库存后，并创建订单完成
            OrderInfo orderInfo = orderInfoService.doSeckill(message.getUserPhone(), message.getTime(), message.getSeckillId());
            //订单创建成功
            orderMQResult.setOrderNo(orderInfo.getOrderNo());
            orderMQResult.setCode(Result.SUCCESS_CODE);
            orderMQResult.setMsg(MQConstant.ORDER_RESULT_SUCCESS_TAG);
            //订单创建成功后，则RocketMQ发送延迟消息，用于检查订单超时未支付的状态，进行自动取消订单，回滚操作
            message.setOrderNo(orderInfo.getOrderNo());
            Message<OrderMessage> delayMessage = MessageBuilder.withPayload(message).build();
            rocketMQTemplate.asyncSend(
                    MQConstant.ORDER_PAY_TIMEOUT_TOPIC,
                    delayMessage,
                    new DefaultMessageSendCallback("订单超时未支付检查"),
                    3000,
                    MQConstant.ORDER_PAY_TIMEOUT_DELAY_LEVEL);
        } catch (BusinessException e) {
            //扣库存操作，如果库存不足则会抛出异常，为了让后面Exception捕获的是订单创建失败的异常，而不是我们自己抛出的异常
            //解决方案：先捕获我们自己抛出的异常进去处理，其他异常则是导致订单创建失败的异常
            log.warn(e.getMessage());
        } catch (Exception e) {
            //订单创建失败
            orderMQResult.setCode(Result.ERROR_CODE);
            orderMQResult.setMsg(MQConstant.ORDER_RESULT_FAIL_TAG);
            //回补Redis中的库存数量，删除Redis中用户是否已经下单标识，删除用户是否已经下过订单的本地标识
            orderInfoService.orderCreateFailedRollback(message);
        }
        //把订单信息结果发送到MQ
        rocketMQTemplate.asyncSend(
                MQConstant.ORDER_RESULT_TOPIC,
                orderMQResult,
                new DefaultMessageSendCallback("订单结果"));
    }
}
